/**
 * 地理位置组合式API
 * 提供响应式的地理位置功能
 */

import { ref, computed, onMounted, onUnmounted } from 'vue'
import locationUtils from '@/utils/location'
import { ElMessage } from 'element-plus'

export function useLocation(options = {}) {
  const {
    autoLoad = true,
    showMessage = true,
    enableHighAccuracy = true,
    timeout = 10000,
    maximumAge = 300000
  } = options

  // 响应式状态
  const location = ref(null)
  const loading = ref(false)
  const error = ref(null)

  // 计算属性
  const hasLocation = computed(() => !!location.value)
  const isGPSLocation = computed(() => location.value?.source === 'gps')
  const isIPLocation = computed(() => location.value?.source === 'ip')
  const isDefaultLocation = computed(() => location.value?.source === 'default')

  // 位置参数（用于API调用）
  const locationParams = computed(() => {
    if (!location.value) {
      return { city: '北京' }
    }

    if (location.value.latitude && location.value.longitude) {
      return {
        lat: location.value.latitude,
        lng: location.value.longitude
      }
    }

    return { city: location.value.city || '北京' }
  })

  /**
   * 获取当前位置
   */
  const getCurrentLocation = async () => {
    loading.value = true
    error.value = null

    try {
      const locationData = await locationUtils.getCurrentLocation({
        enableHighAccuracy,
        timeout,
        maximumAge,
        showMessage
      })

      location.value = locationData
      return locationData
    } catch (err) {
      error.value = err
      if (showMessage) {
        ElMessage.error('获取位置失败: ' + err.message)
      }
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * 刷新位置
   */
  const refreshLocation = async () => {
    // 清除缓存，强制重新获取
    locationUtils.clearCache()
    return await getCurrentLocation()
  }

  /**
   * 地理编码
   */
  const geocode = async (address) => {
    loading.value = true
    error.value = null

    try {
      const result = await locationUtils.geocode(address)
      location.value = result
      return result
    } catch (err) {
      error.value = err
      if (showMessage) {
        ElMessage.error('地理编码失败: ' + err.message)
      }
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * 逆地理编码
   */
  const reverseGeocode = async (lat, lng) => {
    loading.value = true
    error.value = null

    try {
      const result = await locationUtils.reverseGeocode(lat, lng)
      location.value = result
      return result
    } catch (err) {
      error.value = err
      if (showMessage) {
        ElMessage.error('逆地理编码失败: ' + err.message)
      }
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * 搜索地点
   */
  const searchLocation = async (keyword, city) => {
    try {
      return await locationUtils.searchLocation(keyword, city)
    } catch (err) {
      if (showMessage) {
        ElMessage.error('搜索地点失败: ' + err.message)
      }
      throw err
    }
  }

  /**
   * 设置位置
   */
  const setLocation = (locationData) => {
    location.value = locationData
    locationUtils.currentLocation = locationData
  }

  /**
   * 清除位置
   */
  const clearLocation = () => {
    location.value = null
    locationUtils.clearCache()
  }

  /**
   * 计算距离
   */
  const calculateDistance = (targetLat, targetLng) => {
    if (!location.value || !location.value.latitude || !location.value.longitude) {
      return null
    }

    return locationUtils.calculateDistance(
      location.value.latitude,
      location.value.longitude,
      targetLat,
      targetLng
    )
  }

  // 监听位置变化
  let watchId = null

  /**
   * 开始监听位置变化
   */
  const watchPosition = () => {
    if (!navigator.geolocation) {
      console.warn('浏览器不支持地理位置')
      return
    }

    watchId = navigator.geolocation.watchPosition(
      async (position) => {
        try {
          const { latitude, longitude } = position.coords
          const locationData = await locationUtils.reverseGeocode(latitude, longitude)
          location.value = {
            ...locationData,
            source: 'gps',
            accuracy: position.coords.accuracy,
            timestamp: Date.now()
          }
        } catch (err) {
          console.error('位置监听失败:', err)
        }
      },
      (err) => {
        console.error('位置监听错误:', err)
      },
      {
        enableHighAccuracy,
        timeout,
        maximumAge
      }
    )
  }

  /**
   * 停止监听位置变化
   */
  const clearWatch = () => {
    if (watchId !== null) {
      navigator.geolocation.clearWatch(watchId)
      watchId = null
    }
  }

  // 生命周期
  onMounted(() => {
    if (autoLoad) {
      getCurrentLocation()
    }
  })

  onUnmounted(() => {
    clearWatch()
  })

  return {
    // 状态
    location,
    loading,
    error,

    // 计算属性
    hasLocation,
    isGPSLocation,
    isIPLocation,
    isDefaultLocation,
    locationParams,

    // 方法
    getCurrentLocation,
    refreshLocation,
    geocode,
    reverseGeocode,
    searchLocation,
    setLocation,
    clearLocation,
    calculateDistance,
    watchPosition,
    clearWatch
  }
}

export default useLocation
